#include <iostream>
#include <memory>
#include <cstdio>
#include "util.hpp"
#include "config.hpp"
#include "data.hpp"
#include "hot.hpp"
#include "service.hpp"
#include <thread>

const std::string fname = "./test";

// 文件属性测试
void UtilTest1(const std::string filename)
{
    cloud::FileUtil fu(filename);
    // std::unique_ptr<cloud::FileUtil> fu(new FileUtil(filename));

    // fu->FileSize();
    // fu->FileName();
    // fu->LastAccTime();
    // fu->LastModTime();
    std::cout << fu.FileSize() << std::endl;
    std::cout << fu.FileName() << std::endl;
    std::cout << fu.LastATime() << std::endl;
    ;
    std::cout << fu.LastMTime() << std::endl;
}

// 文件读写测试
void UtilTest2(const std::string filename)
{
    // 可以使用md5sum，来测试两个文件是否相同
    cloud::FileUtil fu(filename);
    std::string body;
    fu.GetContent(&body);

    cloud::FileUtil nfu("test.txt");
    nfu.SetContent(body);
}

// 文件压缩与解压缩测试
void UtilTest3(const std::string filename)
{
    std::string packname = filename + ".lz";
    cloud::FileUtil fu(filename);
    fu.Compress(packname);
    cloud::FileUtil pfu(packname);
    pfu.UnCompress("./test.txt"); // 将解压缩的文件放到test.txt中
}

// 目录操作测试
void UtilTest4(const std::string filename)
{
    cloud::FileUtil fu(filename);
    fu.CreateDirectory();

    std::vector<std::string> arry;
    fu.ScanDirectory(&arry);
    for (const auto &e : arry)
    {
        std::cout << e << std::endl;
    }
}

// Json工具测试
void JsonUtilTest1()
{
    const char *name = "张三";
    int age = 19;
    float score[3] = {86, 87, 88};

    // 序列化
    Json::Value root;
    root["姓名"] = name;
    root["年龄"] = age;
    root["成绩"].append(score[0]);
    root["成绩"].append(score[1]);
    root["成绩"].append(score[2]);

    std::string json_str;
    cloud::JsonUtil::Serialize(root, &json_str);
    std::cout << json_str << std::endl;

    // 反序列化
    Json::Value val;
    cloud::JsonUtil::UnSerialize(json_str, &val);
    std::cout << val["姓名"].asString() << std::endl;
    std::cout << val["年龄"].asInt() << std::endl;
    for (int i = 0; i < val["成绩"].size(); i++)
    {
        std::cout << val["成绩"][i].asFloat() << std::endl;
    }
}

// 单例类测试
void ConfigTest()
{
    cloud::Config *config = cloud::Config::GetInstance();
    std::cout << config->GetHotTime() << std::endl;
    std::cout << config->GetServerPort() << std::endl;
    std::cout << config->GetServerIp() << std::endl;
    std::cout << config->GetDownloadPrefix() << std::endl;
    std::cout << config->GetPackFileSuffix() << std::endl;
    std::cout << config->GetPackDir() << std::endl;
    std::cout << config->GetBackDir() << std::endl;
    std::cout << config->GetBackupFile() << std::endl;
}

// 数据类测试
void DataTest(const std::string &realpath)
{
    // cloud::DataManager data;
    // std::vector<cloud::BackupInfo> arry;
    // data.GetAll(&arry);
    // for (auto &a : arry){
    // 	std::cout << a.pack_flag << std::endl;
    // 	std::cout << a.fsize<< std::endl;
    // 	std::cout << a.mtime<< std::endl;
    // 	std::cout << a.atime<< std::endl;
    // 	std::cout << a.real_path << std::endl;
    // 	std::cout << a.pack_path<< std::endl;
    // 	std::cout << a.url<< std::endl;
    // }

    cloud::BackupInfo info;
    info.NewBackupInfo(realpath);
    cloud::DataManager data;
    std::cout << "-----------insert and GetOneByURL------------\n";

    data.Insert(info);
    cloud::BackupInfo tmp;
    data.GetOneByURL("/download/bundle.h", &tmp);
    std::cout << info.pack_flag << std::endl;
    std::cout << info.fsize << std::endl;
    std::cout << info.mtime << std::endl;
    std::cout << info.atime << std::endl;
    std::cout << info.real_path << std::endl;
    std::cout << info.pack_path << std::endl;
    std::cout << info.url << std::endl;

    std::cout << tmp.pack_flag << std::endl;
    std::cout << tmp.fsize << std::endl;
    std::cout << tmp.mtime << std::endl;
    std::cout << tmp.atime << std::endl;
    std::cout << tmp.real_path << std::endl;
    std::cout << tmp.pack_path << std::endl;
    std::cout << tmp.url << std::endl;

    std::cout << "-----------updata and getall------------\n";

    info.pack_flag = true;
    data.Update(info);
    std::vector<cloud::BackupInfo> arry;
    data.GetAll(&arry);
    for(auto &a : arry)
    {
        std::cout << a.pack_flag << std::endl;
        std::cout << a.fsize << std::endl;
        std::cout << a.mtime << std::endl;
        std::cout << a.atime << std::endl;
        std::cout << a.real_path << std::endl;
        std::cout << a.pack_path << std::endl;
        std::cout << a.url << std::endl;
    }
    std::cout << "-----------GetOneByRealPath------------\n";
    data.GetOneByRealPath(realpath, &tmp);
    std::cout << tmp.pack_flag << std::endl;
    std::cout << tmp.fsize << std::endl;
    std::cout << tmp.mtime << std::endl;
    std::cout << tmp.atime << std::endl;
    std::cout << tmp.real_path << std::endl;
    std::cout << tmp.pack_path << std::endl;
    std::cout << tmp.url << std::endl;
}

// 热点类测试
cloud::DataManager *_data;
void HotTest()
{
    _data = new cloud::DataManager();
    cloud::HotManager hot;
    hot.RunModule();
}

// 服务端测试
void ServiceTest()
{
    cloud::Service srv;
    srv.RunModule();
}

int main(int argc, char *argv[])
{
    _data = new cloud::DataManager();
    // JsonUtilTest1();
    // UtilTest1(fname);
    // UtilTest2("./log.txt");
    UtilTest3("./log.txt");
    // UtilTest4("./store");

    // ConfigTest();
    // DataTest(argv[1]);
    // HotTest();
    // ServiceTest();
    // std::thread thread_hot_manager(HotTest);
    // std::thread thread_service(ServiceTest);
    // thread_hot_manager.join();
    // thread_service.join();

    return 0;
}